﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Cognize.GoogleSearchAPIIntegration;
using System.Text;
using System.Runtime.Serialization.Json;
using System.Net;

public partial class Controls_GoogleSearchResultsViewer : System.Web.UI.UserControl
{
    protected void Page_Init( object sender, EventArgs e )
    {
        // Clear results for fresh search
        uc_googleSearchResultPnl.Controls.Clear();

        int resultCountStartPos = 0;
        string searchString = Request.QueryString[ "SearchString" ];

        ResponseData responseData = null;

        try
        {
            searchString = HttpUtility.UrlEncode(searchString.Trim());

            using (WebClient client = new WebClient())
            {
                // Manipulate request headers - Google rest API requires valid result header
                // hence the use of Web client as opposed to WebRequest
                client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");

                // Result size is rsz in query string. This parameter causes the
                // api to return results in sets of 8 where 'large' is used
                // rather than 4 if 'small' is used, so less total api requests are required.

                string resultSize = "large";

                string searchRequestURL = "http://ajax.googleapis.com/ajax/services/search/web?v=1.0&start=" + resultCountStartPos.ToString() + "&rsz=" + resultSize + "&q="  + searchString;

                DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(GoogleAPISearchResults));

                // Read our search results into a .net object
                GoogleAPISearchResults searchResultsObj = (GoogleAPISearchResults)jsonSerializer.ReadObject(client.OpenRead(searchRequestURL));

                responseData = searchResultsObj.responseData;
            }
        }
        catch (Exception ex)
        {
            // Log error here

            // Allow exception to bubble up

            throw ex;
        }

        if (!String.IsNullOrEmpty( searchString ))
        {
            string site = SiteToSearch;

            int searchResultsRequested = MaxSearchResults;

            // Default to 8 results where no
            // value specified.
            if (searchResultsRequested == 0)
            {
                searchResultsRequested = 8;
            }

            SortedList<int, Results> googleSearchResults = GoogleSearch.GetSearchResults( site, searchString, searchResultsRequested );

            if (googleSearchResults.Count > 0)
            {
                PopulateResultsPnl( googleSearchResults );
            }
            else
            {
                DisplayNoResultsMessage();
            }
        }
    }

    private void DisplayNoResultsMessage()
    {
        Literal resultsLiteral = new Literal();
        resultsLiteral.Text = "<span class=\"noResultsMessage\">Sorry, there are no results for your search.</span>";

        uc_googleSearchResultPnl.Controls.Add( resultsLiteral );
    }

    private void PopulateResultsPnl( SortedList<int, Results> googleSearchResults )
    {
        StringBuilder resultHtmlStringBuilder = new StringBuilder();

        for (int i = 0; i < googleSearchResults.Count; i++)
        {
            resultHtmlStringBuilder.Append( "<div class=\"resultItem\">" );
            resultHtmlStringBuilder.Append( "<h2>" );
            resultHtmlStringBuilder.Append( (i + 1).ToString() );
            resultHtmlStringBuilder.Append( ". <a href=\"ViewPage.aspx?url=" );
            resultHtmlStringBuilder.Append( Uri.EscapeDataString(googleSearchResults[i].url) );
            resultHtmlStringBuilder.Append( "\">" );
            resultHtmlStringBuilder.Append( googleSearchResults[i].title );    
            resultHtmlStringBuilder.Append( "</a></h2>" );
            resultHtmlStringBuilder.Append( "<p><a href=\"ViewPage.aspx?type=1&url=" );
            resultHtmlStringBuilder.Append(Uri.EscapeDataString(googleSearchResults[i].url));
            resultHtmlStringBuilder.Append( "\">" );
            resultHtmlStringBuilder.Append( googleSearchResults[i].content );
            resultHtmlStringBuilder.Append( "</a><br />" );
            resultHtmlStringBuilder.Append("<em><a href=\"");
            resultHtmlStringBuilder.Append( googleSearchResults[i].url );
            resultHtmlStringBuilder.Append( "\">" );
            resultHtmlStringBuilder.Append( googleSearchResults[i].url );
            resultHtmlStringBuilder.Append( "</a></em></p>" );
            resultHtmlStringBuilder.Append( "</div>" );
        }

        Literal resultsLiteral = new Literal();
        resultsLiteral.Text = resultHtmlStringBuilder.ToString();

        uc_googleSearchResultPnl.Controls.Add( resultsLiteral );
    }

    /// <summary>
    /// The fully qualified domain of the site for which search should be restricted (optional).
    /// </summary>
    public string SiteToSearch
    {
        get { return _SiteToSearch; }
        set { _SiteToSearch = value; }
    }

    /// <summary>
    /// The maximum number of results required.
    /// </summary>
    public int MaxSearchResults
    {
        get { return _MaxSearchResults; }
        set { _MaxSearchResults = value; }
    }
    private string _SiteToSearch;
    private int _MaxSearchResults;
}
